/** @file
 * @brief Utility functions for time manipulation */
#ifndef __TIME_FUNCS_H_
#define __TIME_FUNCS_H_

/* Author: Ratish J. Punnoose, 2006
 * This file is part of TiROS, the Tickless Real-Time Operating System.
 * Copyright(c) 2006, 2007: Ratish J. Punnoose.
 * Copyright(c) 2006 Sandia Corporation. Under the terms of Contract
 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
 * certain rights in this software. 
 * 
 * TiROS is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 or (at your option) any later version.
 *
 * TiROS is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with TiROS; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * As a special exception, if other files instantiate templates or use macros
 * or inline functions from this file, or you compile this file and link it
 * with other works to produce a work based on this file, this file does not
 * by itself cause the resulting work to be covered by the GNU General Public
 * License. However the source code for this file must still be made available
 * in accordance with section (3) of the GNU General Public License.
 *
 * This exception does not invalidate any other reasons why a work based on
 * this file might be covered by the GNU General Public License.
 *
 */




#ifndef subtime_t
#error "Don't include tr_time.h directly.  Include tiros.h or tr_port.h"
#endif

/** @defgroup os_time_utils Utility functions for time operations
 * @{ */

/** Time structure
 *
 * Different hardware architectures may represent time in formats that
 * are most efficient and suitable  for that hardware.  We impose no
 * requirements except for two functions that can convert this hardware
 * dependent time structure into units of seconds and vice-versa
 * The trtime_t structure consists of two elements:
 * <OL>
 * <LI> A subsecond unit (could be milli-seconds, nano-seconds,etc.) </LI>
 * <LI> A supersecond unit ( could be a unit of 1 second, 10 secs, 1
 *    minute etc. </LI>
 * </OL>
 * This choice of time is kept deliberately vague, since the
 * application is an embedded system, where these functions have to be
 * fast, take advantage of the hardware, and cannot waste cycles
 * converting time units from the hardware representation to a
 * standard form.
 */
typedef struct trtime {
	uint32_t  	units;    /**< Time in secs preferably (but
				    * no requirement) */
	subtime_t  	subunits;   /**< Sub-seconds: hardware   dependent */
} trtime_t;


#ifndef LT_INLINE
#define LT_INLINE
#endif

/** Convert time represented in trtime to seconds
 * @param [in] lt  Pointer to trtime structure.
 * @return Equivalent time in seconds */
LT_INLINE uint32_t  trtime_to_secs(const trtime_t * const lt);

/** Convert time represented in seconds to trtime
 * @param seconds  Time in seconds to be converted.
 * @param [out] lt  Pointer to trtime structure. */
LT_INLINE void  secs_to_trtime(uint32_t seconds, trtime_t *lt);



/** Time subtraction
 *
 * Note: Time1 >= Time2, check using time_compare if needed.
 * @param x  Time1
 * @param y  Time2
 * @param [out] res  Time1 - Time 2 */
LT_INLINE void time_sub(const trtime_t * x, 
			const trtime_t * y, trtime_t *res);

/** Time addition
 * @param x  Time1
 * @param y  Time2
 * @param [out] res  Time1 + Time 2 */
LT_INLINE void time_add(const trtime_t * x, const trtime_t * y, trtime_t *res);

/** Time comparison
 * @param t1  Time1
 * @param t2  Time2
 * @Return   (-1,0,1) depending on whether t1 < t2, t1==t2, t1 > t2  */
LT_INLINE int time_compare(const trtime_t * t1, const trtime_t *  t2);


/** Time less than
 * @param t1  Time1
 * @param t2  Time2
 * @Return   (1,0) depending on whether t1 < t2.  This can easily be
 * implemented using time_compare  but is provided as an optimization. */
LT_INLINE int time_lessthan(const trtime_t * t1, const trtime_t *  t2);


/** @} End utility time functions module */


#endif
